package com.yonyou.openapi.base.http;

import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpRequest;
import org.apache.http.NoHttpResponseException;
import org.apache.http.annotation.Contract;
import org.apache.http.annotation.ThreadingBehavior;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.methods.HttpRequestWrapper;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.protocol.HttpContext;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.SocketTimeoutException;

/**
 * @author nishch
 * @description: 重试机制处理
 * @date 2023/9/26
 */
@Slf4j
@Contract(threading = ThreadingBehavior.IMMUTABLE)
public class APIHttpRequestRetryHandler implements HttpRequestRetryHandler {
    @SneakyThrows
    @Override
    public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
        if(executionCount>3){
            HttpClientContext httpClientContext = HttpClientContext.adapt(context);
            HttpRequest httpRequest = httpClientContext.getRequest();
            InputStream inputStream = ((HttpEntityEnclosingRequest)httpRequest).getEntity().getContent();
            String reqParams = exceptionRequestEntity(inputStream);
            log.error("请求参数:"+reqParams+",响应异常提示:"+exception.getMessage());
            return false;
        }
        return exception instanceof SocketTimeoutException || exception instanceof ConnectTimeoutException || exception instanceof NoHttpResponseException;
    }


    private String exceptionRequestEntity(InputStream inputStream){
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        try {
            byte[] b = new byte[1024];
            int n;
            while ((n = inputStream.read(b))!=-1){
                byteArrayOutputStream.write(b,0,n);
            }
        }catch (Exception e){
            log.error("重试解析数据异常");
        }finally {
            try{
                inputStream.close();
                byteArrayOutputStream.close();
            }catch (Exception e1){
                log.error("重试解析数据关闭流异常");
            }
        }
        return byteArrayOutputStream.toString();
    }
}
